# coding: utf-8

import os
import sys
import asyncio

# 设置Windows控制台编码为UTF-8
if sys.platform == 'win32':
    try:
        # 尝试设置控制台代码页为UTF-8
        os.system('chcp 65001 >nul 2>&1')
    except:
        pass
import signal
from pathlib import Path
from platform import system
from typing import List

import typer
import colorama
import keyboard

from config import ClientConfig as Config
from util.client_cosmic import console, Cosmic
from util.client_stream import stream_open, stream_close
from util.client_shortcut_handler import bond_shortcut
from util.client_recv_result import recv_result
from util.client_show_tips import show_mic_tips, show_file_tips
from util.client_hot_update import update_hot_all, observe_hot

from util.client_transcribe import transcribe_check, transcribe_send, transcribe_recv
from util.client_adjust_srt import adjust_srt

from util.empty_working_set import empty_current_working_set

# Import logging system
from util.logging import setup_logging, get_logger, SystemHealthLogger, PerformanceTracker

# 确保根目录位置正确，用相对路径加载模型
BASE_DIR = os.path.dirname(__file__); os.chdir(BASE_DIR)

# 确保终端能使用 ANSI 控制字符
colorama.init()

# MacOS 的权限设置
if system() == 'Darwin' and not sys.argv[1:]:
    if os.getuid() != 0:
        print('在 MacOS 上需要以管理员启动客户端才能监听键盘活动，请 sudo 启动')
        input('按回车退出'); sys.exit()
    else:
        os.umask(0o000)


async def main_mic():
    # Initialize logging system
    setup_logging(profile=os.environ.get('CAPSWRITER_LOG_PROFILE', 'production'))
    logger = get_logger('capswriter.client')
    
    # Initialize system health monitoring
    health_logger = SystemHealthLogger()
    health_logger.log_startup_info()
    
    # Initialize performance tracking
    perf_tracker = PerformanceTracker('capswriter.client.performance')
    perf_tracker.start_operation('client_startup')
    
    logger.info("Starting CapsWriter Client - Microphone Mode")
    logger.info(f"Server address: {Config.addr}:{Config.port}")
    logger.info(f"Shortcut key: {Config.shortcut}")
    
    try:
        Cosmic.loop = asyncio.get_event_loop()
        Cosmic.queue_in = asyncio.Queue()
        Cosmic.queue_out = asyncio.Queue()

        show_mic_tips()

        # 更新热词
        logger.info("Updating hot keywords")
        update_hot_all()

        # 实时更新热词
        logger.debug("Starting hot keyword observer")
        observer = observe_hot()

        # 打开音频流
        logger.info("Opening audio stream")
        Cosmic.stream = stream_open()
        logger.info("Audio stream opened successfully")

        # Ctrl-R 关闭音频流，触发自动重启 (保留原功能)
        def restart_stream_handler(signum, frame):
            logger.info("Stream restart requested by user (Ctrl-R)")
            stream_close(signum, frame)
        
        # 在 Windows 上绑定 Ctrl-R 用于重启音频流
        if system() == 'Windows':
            try:
                import signal
                # 注意：在 Windows 上只能捕获 SIGINT，我们改用键盘监听
                keyboard.add_hotkey('ctrl+r', lambda: stream_close(None, None))
                logger.info("Stream restart hotkey bound: Ctrl+R")
            except Exception as e:
                logger.warning(f"Failed to bind stream restart hotkey: {e}")
        
        # Ctrl-C 现在用于正常退出程序

        # 绑定按键
        logger.info(f"Binding shortcut key: {Config.shortcut}")
        bond_shortcut()
        logger.info("Shortcut key bound successfully")

        # 清空物理内存工作集
        if system() == 'Windows':
            try:
                empty_current_working_set()
                logger.debug("Memory working set cleared")
            except Exception as e:
                logger.warning("Failed to clear memory working set", exc_info=e)

        # Log client startup completion
        startup_time = perf_tracker.end_operation('client_startup')
        logger.info(f"Client startup completed in {startup_time:.2f} seconds")
        logger.info("Client ready for voice input")

        # 接收结果
        while True:
            await recv_result()
            
    except Exception as e:
        logger.error("Error in microphone mode", exc_info=e)
        raise


async def main_file(files: List[Path]):
    # Initialize logging system
    setup_logging(profile=os.environ.get('CAPSWRITER_LOG_PROFILE', 'production'))
    logger = get_logger('capswriter.client.file')
    
    # Initialize performance tracking
    perf_tracker = PerformanceTracker('capswriter.client.file.performance')
    
    logger.info(f"Starting CapsWriter Client - File Mode")
    logger.info(f"Processing {len(files)} files")
    
    show_file_tips()

    try:
        for i, file in enumerate(files, 1):
            logger.info(f"Processing file {i}/{len(files)}: {file}")
            perf_tracker.start_operation(f'file_processing_{i}')
            
            try:
                if file.suffix in ['.txt', '.json', 'srt']:
                    logger.info(f"Adjusting SRT file: {file}")
                    adjust_srt(file)
                else:
                    logger.info(f"Transcribing audio file: {file}")
                    await transcribe_check(file)
                    await asyncio.gather(
                        transcribe_send(file),
                        transcribe_recv(file)
                    )
                
                processing_time = perf_tracker.end_operation(f'file_processing_{i}')
                logger.info(f"File {file} processed successfully in {processing_time:.2f} seconds")
                
            except Exception as e:
                logger.error(f"Failed to process file {file}", exc_info=e)
                raise

        logger.info("All files processed successfully")
        
    except Exception as e:
        logger.error("Error in file processing mode", exc_info=e)
        raise
    finally:
        if Cosmic.websocket:
            logger.info("Closing WebSocket connection")
            await Cosmic.websocket.close()
        
    input('\n按回车退出\n')


def init_mic():
    logger = None
    try:
        asyncio.run(main_mic())
    except KeyboardInterrupt:
        if logger:
            logger.info("Client shutdown requested by user (Ctrl-C)")
        console.print(f'再见！')
    except Exception as e:
        if not logger:
            setup_logging()
            logger = get_logger('capswriter.client')
        logger.error("Unexpected client error", exc_info=e)
        # 处理错误消息的编码问题
        try:
            error_msg = str(e)
            error_msg.encode('gbk')
            console.print(f'客户端错误：{error_msg}', style='bright_red')
        except UnicodeEncodeError:
            console.print('客户端发生错误（包含特殊字符）', style='bright_red')
    finally:
        if logger:
            logger.info("Client cleanup completed")
        print('...')


def init_file(files: List[Path]):
    """
    用 CapsWriter Server 转录音视频文件，生成 srt 字幕
    """
    logger = None
    try:
        asyncio.run(main_file(files))
    except KeyboardInterrupt:
        if logger:
            logger.info("File processing interrupted by user (Ctrl-C)")
        console.print(f'再见！')
        sys.exit()
    except Exception as e:
        if not logger:
            setup_logging()
            logger = get_logger('capswriter.client.file')
        logger.error("Unexpected file processing error", exc_info=e)
        console.print(f'文件处理错误：{e}', style='bright_red')
        sys.exit(1)


if __name__ == "__main__":
    # 如果参数传入文件，那就转录文件
    # 如果没有多余参数，就从麦克风输入
    if sys.argv[1:]:
        typer.run(init_file)
    else:
        init_mic()
